package com.zyj.benchmark.test.sort;

import cn.hutool.core.util.RandomUtil;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.concurrent.TimeUnit;

@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 1, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 1, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(1)
@State(Scope.Thread)
public class SortBenchmark {

    int[] arr;

    @Setup(Level.Invocation)
    public void prepareArray() {
        arr = new int[10];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = RandomUtil.randomInt(0, 100);
        }
    }

    @Benchmark
    public int[] bubbleSort() throws Exception {
        return BubbleSort.sort(arr);
    }

    @Benchmark
    public int[] bucketSort() throws Exception {
        return BucketSort.sort(arr);
    }

    @Benchmark
    public int[] countingSort() throws Exception {
        return CountingSort.sort(arr);
    }

    @Benchmark
    public int[] heapSort() throws Exception {
        return HeapSort.sort(arr);
    }

    @Benchmark
    public int[] insertionSort() throws Exception { // n²
        return InsertSort.sort(arr);
    }

    @Benchmark
    public int[] mergeSort() throws Exception { // nlog(n)
        return MergeSort.sort(arr);
    }

    @Benchmark
    public int[] quickSort() throws Exception {
        return QuickSort.sort(arr);
    }

    @Benchmark
    public int[] radixSort() throws Exception {
        return RadixSort.sort(arr);
    }

    @Benchmark
    public int[] selectionSort() throws Exception {
        return SelectionSort.sort(arr);
    }

    @Benchmark
    public int[] shellSort() throws Exception {
        return ShellSort.sort(arr);
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(SortBenchmark.class.getSimpleName())
                .resultFormat(ResultFormatType.JSON)
                .result("/F:/tmp/"+ SortBenchmark.class.getSimpleName()+".json")
                .build();
        new Runner(opt).run();
    }
    //java -jar benchmarks.jar -rf json
    //java -jar benchmarks.jar -lrf
    //Available formats: text, csv, scsv, json, latex

}

//数组长度10
//Benchmark                    Mode  Cnt     Score   Error  Units
//SortBenchmark.bubbleSort     avgt        176.149          ns/op
//SortBenchmark.bucketSort     avgt       1044.848          ns/op
//SortBenchmark.countingSort   avgt        247.942          ns/op
//SortBenchmark.heapSort       avgt        230.058          ns/op
//SortBenchmark.insertionSort  avgt        118.241          ns/op
//SortBenchmark.mergeSort      avgt        816.673          ns/op
//SortBenchmark.quickSort      avgt        220.362          ns/op
//SortBenchmark.radixSort      avgt       6901.228          ns/op
//SortBenchmark.selectionSort  avgt        147.226          ns/op
//SortBenchmark.shellSort      avgt        183.942          ns/op


//数组长度 100
//取值范围 0 ~ 100
//Benchmark                    Mode  Cnt      Score   Error  Units
//SortBenchmark.bubbleSort     avgt       15971.427          ns/op
//SortBenchmark.bucketSort     avgt        5975.494          ns/op
//SortBenchmark.countingSort   avgt        1102.195          ns/op
//SortBenchmark.heapSort       avgt        4872.969          ns/op
//SortBenchmark.insertionSort  avgt        1903.621          ns/op
//SortBenchmark.mergeSort      avgt       19693.174          ns/op
//SortBenchmark.quickSort      avgt        3852.657          ns/op
//SortBenchmark.radixSort      avgt       16082.577          ns/op
//SortBenchmark.selectionSort  avgt        7024.897          ns/op
//SortBenchmark.shellSort      avgt        3786.523          ns/op


//数组长度10000
//Benchmark                    Mode  Cnt          Score   Error  Units
//SortBenchmark.bubbleSort     avgt       135785150.250          ns/op
//SortBenchmark.bucketSort     avgt         1872753.123          ns/op
//SortBenchmark.countingSort   avgt           25411.636          ns/op
//SortBenchmark.heapSort       avgt          896633.502          ns/op
//SortBenchmark.insertionSort  avgt         8564240.154          ns/op
//SortBenchmark.mergeSort      avgt        28881710.838          ns/op
//SortBenchmark.quickSort      avgt          635650.575          ns/op
//SortBenchmark.radixSort      avgt         5491800.536          ns/op
//SortBenchmark.selectionSort  avgt        28410974.833          ns/op
//SortBenchmark.shellSort      avgt          744406.942          ns/op